package cn.lym.zxxx.session.impl;

import cn.lym.zxxx.config.SessionConfig;
import cn.lym.zxxx.redis.RedisClient;
import cn.lym.zxxx.redis.SimpleRedisClient;
import cn.lym.zxxx.request.ShareHttpServletRequest;
import cn.lym.zxxx.session.ShareSessionManager;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisShareSessionManager implements ShareSessionManager {
    private final String SESSION_NAME_PRE = "SHARE_SESSION";
    private final String SESSION_PROPERTY_PRE = "SHARE_SESSION";

    private RedisClient redisClient = null;

    private Map<String, RedisShareHttpSession> sessionCache = new HashMap<>();

    @Override
    public void init() {
        //TODO
        String jedisHost = SessionConfig.getValue("redis.host");
        String jedisPassword = SessionConfig.getValue("redis.password");
        String host = jedisHost.split(":")[0];
        int port = Integer.parseInt(jedisHost.split(":")[1]);
        JedisPoolConfig config = new JedisPoolConfig();
        JedisPool jedisPool = null;
        if (jedisPassword == null) {
            jedisPool = new JedisPool(config, host, port, 30);
        } else {
            jedisPool = new JedisPool(config, host, port, 30, jedisPassword);
        }
        redisClient = new SimpleRedisClient(jedisPool);
    }

    private RedisShareHttpSession createNewSession(ShareHttpServletRequest shareRequest) {
        String sessionId = shareRequest.getSessionId();
        HttpSession originalSession = ((HttpServletRequest) shareRequest.getRequest()).getSession();
        long createTime = System.currentTimeMillis();
        RedisShareHttpSession shareHttpSession = new RedisShareHttpSession(sessionId, this, originalSession, createTime, true, this.redisClient);
        this.destroySession(sessionId);
        this.sessionCache.put(sessionId, shareHttpSession);
        return shareHttpSession;
    }

    @Override
    public HttpSession getOrCreateSession(String sessionId, HttpServletRequest request, HttpServletResponse response, boolean create) {
        if (!(request instanceof ShareHttpServletRequest)) {
            throw new IllegalStateException("serlvet类型不匹配");
        }
        ShareHttpServletRequest shareRequest = (ShareHttpServletRequest) request;
        HttpSession originalSession = ((HttpServletRequest) shareRequest.getRequest()).getSession();
        if (create) {
            return createNewSession(request);
        }

        RedisShareHttpSession redisShareHttpSession = sessionCache.get(sessionId);
        if (redisShareHttpSession == null) {

        }


        //sessionid不为空，判断redis中是否存在该session的相关信息
        Boolean exist = redisUtil.exists(sessionId.getBytes());
        if (exist) {
            List<Object> sessionData = redisUtil.hmget(sessionId.getBytes(),
                    sessionTimeoutSeconds, SESSION_ATTR_NAMES.getBytes(),
                    SESSION_BASEDATA.getBytes());
            Set<String> attrNames = (Set<String>) sessionData.get(0);
            BaseSessionData baseSessionData = (BaseSessionData) sessionData.get(1);
            baseSessionData.setLastAccessTimeMillis(System.currentTimeMillis());
            //初始化session
            RedisSessionInternalImpl session = new RedisSessionInternalImpl(sessionId, redisRequest, false, this);
            session.setAttributeNameSet(attrNames);
            session.setSessionId(sessionId);
            session.setBaseSessionData(baseSessionData);
            return session;
        }
        if (create) {
            return createNewSession(request, response);
        } else {
            return null;
        }

        return redisShareHttpSession;
    }

    @Override
    public void destroySession(String sessionId) {
        RedisShareHttpSession redisShareHttpSession = sessionCache.get(sessionId);
        if (redisShareHttpSession != null) {
            redisShareHttpSession.invalidate();
            sessionCache.remove(sessionId);
        }
    }


}
